package com.rxyb.auth.service.impl;

import cn.hutool.core.util.ArrayUtil;
import com.rxyb.auth.feign.pojo.user.UserDetailReq;
import com.rxyb.auth.feign.pojo.user.UserDetailRsp;
import com.rxyb.auth.feign.user.UserFeignServer;
import com.rxyb.core.respone.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

/**
 * @author YJH
 * @version 1.0
 * @description
 * @date 2020/6/6  15:03
 */
@Service
@Slf4j
public class UserDetailsServiceImpl implements UserDetailsService {


    @Autowired
    private UserFeignServer userFeignServer;

    @Autowired
    private HttpServletRequest request;

    /**
     * 根据用户名定位用户。在实际实现中，搜索
     * 可能是区分大小写的，或者不区分大小写，这取决于
     * 已配置实现实例。在本例中，<code>UserDetails</code>
     * 返回的对象可能有不同的用户名
     * 实际上已被请求..
     *
     * @param 标识需要其数据的用户的用户名。
     * @return a fully populated user record (never <code>null</code>)
     * @throws UsernameNotFoundException if the user could not be found or the user has no
     *                                   GrantedAuthority
     */
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        UserDetailReq req = new UserDetailReq();
        req.setUserName(username);
        R<UserDetailRsp> r = userFeignServer.userDetail(req);
        if (!r.ok()) {
            throw new UsernameNotFoundException(r.getMsg());
        }

        Set<String> authSet = new HashSet<>();
        if (ArrayUtil.isNotEmpty(r.getData().getRoles())) {
            Arrays.stream(r.getData().getRoles()).forEach(e -> authSet.add("ROLE_" + e));
            authSet.addAll(Arrays.asList(r.getData().getSysMenuResouces()));
        }
        Collection<? extends GrantedAuthority> authorities
                = AuthorityUtils.createAuthorityList(authSet.toArray(new String[0]));
        return new User(r.getData().getSysUser().getUsername(), r.getData().getSysUser().getPassword(), authorities);
    }
}
